#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

#include <unistd.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <endian.h>

#include "nstar_sntp.h"

#if 1
#define dbg printf
#else
#define dbg(...) 
#endif

#define TIME_ZONE_VAL (3600*8)

static char filter_sntp_b=0,filter_sntp_i=0;
static int myfilter(int *off,int d,char *b,char *i)
{
#define RANK_B 3	
#define RANK_I 3	
	int ret = 0;
	int absoff ;
	absoff = abs(*off);
	if(*b < RANK_B){
		if(*i < RANK_I){ 			
			if(absoff < d)
				(*i)++;	
			else if((*i)>0)
				(*i)--;
		}
		else {					
			if(absoff<(d)){
				if(*b>0){
					(*b)--;
				}
			}
			else {
				(*b)++; 		
				*off = 0; 		
			}
			ret=1;
		}
	}
	else{  						
		*i = 0;
		*b = 0;
	}
	//dbg("off=%d, *i=%d, *b=%d\n",*off,*i,*b);
	return ret;
}

#define ADJUST_OFF 3 //S
#define NSATR_SNTP_FILTER(off)	myfilter(off, ADJUST_OFF, &filter_sntp_b, &filter_sntp_i)

static void adjust_time(struct timeval rec_time)
{
	struct timeval tv;
	gettimeofday(&tv, NULL);
	
	long  off_s;
	unsigned char res=0;
	printf("current  %ld rec %ld\n", tv.tv_sec, rec_time.tv_sec);	
	
	off_s= rec_time.tv_sec- tv.tv_sec;

	NSATR_SNTP_FILTER((int*)&off_s);
	if(abs(off_s) > ADJUST_OFF)
	{
		tv.tv_sec +=  off_s;
		printf("new %ld\n\n", tv.tv_sec);	
		tv.tv_usec = 0;
		res= settimeofday(&tv, NULL);
        if (res != 0) {
            printf("sntp: adjust time %ld.%ld error #%d \n", tv.tv_sec, tv.tv_usec ,res);
        }
		else
			printf("sntp: adjust time %ld.%ld \n", tv.tv_sec, tv.tv_usec);	
	}

}
										          

void read_time(NATAR_OS_TIME *os_time)
{
	struct tm  *sysTime;
	time_t timep;
    time(&timep);
	timep+=TIME_ZONE_VAL;
	sysTime = gmtime(&timep);
	os_time->year = sysTime->tm_year +1900;
	os_time->mon  = sysTime->tm_mon+1;
	os_time->day  = sysTime->tm_mday;
	os_time->hour = sysTime->tm_hour;
	os_time->min  = sysTime->tm_min;
	os_time->sec  = sysTime->tm_sec;
}

void printf_time(void)
{
	NATAR_OS_TIME os_t;
	read_time(&os_t);	
	printf("time %d-%d-%d", (os_t.year), os_t.mon ,os_t.day);
	printf(" %d:%d:%d\n", os_t.hour, os_t.min, os_t.sec);
}

unsigned char ebm_time_handle(unsigned int utc_t)
{
	struct timeval rec_time;
	rec_time.tv_sec= utc_t;
	rec_time.tv_usec=0;
	adjust_time(rec_time);	
	printf_time();
	return 0;
}

unsigned char ebm_set_time(NATAR_OS_TIME p_t)
{
	struct tm o_t={0};

	if(p_t.year >= 2010 && p_t.year <= 2050){
		o_t.tm_sec = (int)(p_t.sec);
		o_t.tm_min = (int)(p_t.min);
		o_t.tm_hour = (int)(p_t.hour);
		o_t.tm_mday = (int)(p_t.day);
		o_t.tm_mon = (int)(p_t.mon)-1;
		o_t.tm_year = p_t.year - 1900;
	}
	long serial_sec = mktime(&o_t);
	printf("settime =%ld\n", serial_sec);
	return 0;
	
}





